Original plot and data

For practice, you will try to recreate a plot published in the Economist issue of July 20th, 2016 reflecting the relationship between well-being and financial inclusion.

  • The original graph can be found here

  • You will generate this figure step by step through a series of included exercises using the tools we’ve just learned and will learn about.

The data for the exercises EconomistData.csv can be downloaded from the class github repository.

url <- paste0("https://raw.githubusercontent.com/cme195/cme195.github.io/",
              "master/assets/data/EconomistData.csv")
dat <- read.csv(url)
head(dat)

Exercise 1

  1. Create a scatter plot with percent of people over the age of 15 with a bank account on the x axis and the SEDA score on the y axis.
  2. Color the points in the previous plot blue.
  3. Color the points in the previous plot according to the Region.
  4. Create boxplots of SEDA scores by Region.
  5. Overlay points on top of the box plots
#1. Create a scatter plot with percent of people over the age of 15 with a bank 
p <- ggplot(dat, aes(x = Percent.of.15plus.with.bank.account, y = SEDA.Current.level)) 
p + geom_point()

#2. Color the points in the previous plot blue.
p + geom_point(color = "blue")

#3. Color the points in the previous plot according to the `Region`.
p + geom_point(aes(color = Region))

#4. Create boxplots of SEDA scores by `Region`.
boxplot <- ggplot(dat, aes(x = Region, y = SEDA.Current.level)) + geom_boxplot() +
  theme(axis.text.x = element_text(angle = 15, hjust = 1))
boxplot

#5. Overlay points on top of the box plots
boxplot + geom_point()

#5. Overlay points on top of the box plots
boxplot + geom_jitter(width = 0.4)

Exercise 2

  1. Re-create a scatter plot with percent of people aged 15+ with a bank account on the x axis and SEDA current level score on the y axis (as you did in the previous exercise).
  2. Overlay a smoothing line on top of the scatter plot using the lm method. Hint: see ?stat_smooth.
  3. Overlay a smoothing line on top of the scatter plot using the default method.
  4. Overlay a smoothing line on top of the scatter plot using the default loess method, but make it less smooth. Hint: see ?loess.
#1. Re-create a scatter plot
p <- ggplot(dat, aes(x = Percent.of.15plus.with.bank.account, y = SEDA.Current.level))
(p <- p + geom_point())

#2. Overlay a smoothing line on top of the scatter plot using the lm method
p + geom_smooth(method = "lm")

#3. Overlay a smoothing line on top of the scatter plot using the default method.
p + geom_smooth()

#4. Overlay a smoothing line on top of the scatter plot using the default loess 
# method, but make it less smooth
p + geom_smooth(span = 0.2)

Exercise 3

  1. For the scatter plot of % of ppl aged 15+ with bank account vs SEDA score colored by region, generated in Exercise I.3 modify the color scale to use specific values of your choosing. Hint: see ?scale_color_manual.
pEc <- ggplot(dat, aes(Percent.of.15plus.with.bank.account, SEDA.Current.level)) 
(pEc <- pEc + geom_point(aes(color = Region)) + scale_color_brewer(palette = "Set1"))

Exercise 4

  1. Facet by region (~ Region) the the Economist plot from Exercise 3.
pEc + facet_wrap(~ Region)

Exercise 5: Finish the Economist plot.

  1. Change order of the Regions
  2. Add the linear trend
  3. Change the axes ratio.
  4. Change the color scheme. Use these colors colors <- c("#28AADC","#F2583F", "#76C0C1","#24576D", "#248E84","#DCC3AA", "#96503F")
  5. Add a title and format the axes
  6. Change the background and theme
  7. Format the legend
  8. Add point labels

Change order of the Regions

dat$Region <- as.character(dat$Region)
dat$Region <- factor(dat$Region, 
                     levels = c("Europe", "Asia", "Oceania", 
                                "North America", 
                                "Latin America & the Caribbean", 
                                "Middle East & North Africa",
                                "Sub-Saharan Africa"),
                     labels = c("Europe", "Asia", "Oceania", 
                                "North America", 
                                "Latin America & \n the Caribbean", 
                                "Middle East & \n North Africa",
                                "Sub-Saharan \n Africa"))
pEc <- ggplot(dat, aes(Percent.of.15plus.with.bank.account, SEDA.Current.level)) 
pEc + geom_point(aes(color = Region))

Add the linear trend

pEc <- pEc + geom_smooth(method = "lm", se = FALSE, col = "black", size = 0.5) 
(pEc <- pEc + geom_point(aes(fill = Region), color = "white", shape = 21, size =4)) 

Change the axes ratio.

(pEc <- pEc + coord_fixed(ratio = 0.4))

Change the color scheme

colors <-  c("#28AADC","#F2583F", "#76C0C1","#24576D", 
             "#248E84","#DCC3AA", "#96503F")
(pEc <- pEc + scale_fill_manual(name = "",
                                values = colors))

Add a title and format the axes

(pEc <- pEc +
  scale_x_continuous(name = "% of people aged 15+ with bank account, 2014",
                     limits = c(0, 100),
                     breaks = seq(0, 100, by = 20)) +
  scale_y_continuous(name = "SEDA Score, 100-maximum",
                     limits = c(0, 100),
                     breaks = seq(0, 100, by = 20)) +
  ggtitle("Laughing all the way to the bank \n Well-being amd financial inclusion \n 2014-15"))

Change the background and theme

You can check out the ggthemes package which implement the themes that make your plots look like they came from:

  • Base graphics
  • Tableau
  • Excel
  • Stata
  • Economist
  • Wall Street Journal
  • Edward Tufte
  • Nate Silver’s Fivethirtyeight
  • etc.
# install.pcakages("ggthemes")
library(ggthemes)
(pEc <- pEc + theme_economist_white(gray_bg=FALSE))

Format the legend

(pEc <- pEc + coord_fixed(0.4) +
   theme(text = element_text(color = "grey37", size = 12),
        legend.position = c(0.45, 1.1), # position the legend in the upper left 
        legend.direction = "horizontal",
        legend.justification = 0.1, # anchor point for legend.position.
        legend.text = element_text(size = 10, color = "gray10"),
        plot.title = element_text(size = rel(1.1), color = "black"),
        plot.margin = unit(c(1, 1.5, 1.5, 0.5), "cm")) +
  guides(fill = guide_legend(ncol = 4, byrow = FALSE)))

Add point labels

pointsToLabel <- c("Yemen", "Iraq", "Egypt", "Jordan", "Chad", "Congo", 
                   "Angola", "Albania", "Zimbabwe", "Uganda", "Nigeria",
                   "Uruguay", "Kazakhstan", "India", "Turkey", "South Africa",
                   "Kenya", "Russia", "Brazil", "Chile", "Saudi Arabia", 
                   "Poland", "China", "Serbia", "United States", "United Kingdom")
(pEcText <-  pEc + geom_text_repel(aes(label = Country), color = "gray20",
                               data = subset(dat, Country %in% pointsToLabel),
                               force = 20))

Add notes to the bottom and save the plot

Use “grid.text()” to add notes

library(grid)
png(file = "./econScatter.png", width = 800, height = 600)
pEcText
grid.text("Source: Boston Consulting Group",
         x = .02, y = .04, just = "left",
         draw = TRUE, gp=gpar(fontsize=10, col="grey37"))
grid.text("Data available for 123 countries \n Sustainable economic development assesment",
         x = 0.98, y = .06, just = "right",
          draw = TRUE, gp=gpar(fontsize=10, col="grey37"))
dev.off()
null device 
          1 

Similar to the original:

LS0tCnRpdGxlOiAiTGVjdHVyZSA0OiBFeGVyY2lzZXMgd2l0aCBhbnN3ZXJzIgpkYXRlOiBPY3RvYmVyIDEydGgsIDIwMTYKb3V0cHV0OiAKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKLS0tCgojIE9yaWdpbmFsIHBsb3QgYW5kIGRhdGEKCkZvciBwcmFjdGljZSwgeW91IHdpbGwgdHJ5IHRvIHJlY3JlYXRlCmEgcGxvdCBwdWJsaXNoZWQgaW4gdGhlIEVjb25vbWlzdCBpc3N1ZSBvZiBKdWx5IDIwdGgsIDIwMTYgcmVmbGVjdGluZwp0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gd2VsbC1iZWluZyBhbmQgZmluYW5jaWFsIGluY2x1c2lvbi4KCiFbXSguL2Vjb25vbWlzdC5wbmcpCgoKKiBUaGUgb3JpZ2luYWwgZ3JhcGggY2FuIGJlIGZvdW5kIApbaGVyZV0oaHR0cDovL3d3dy5lY29ub21pc3QuY29tL2Jsb2dzL2dyYXBoaWNkZXRhaWwvMjAxNi8wNy9kYWlseS1jaGFydC0xMykKCiogWW91IHdpbGwgZ2VuZXJhdGUgdGhpcyBmaWd1cmUgc3RlcCBieSBzdGVwIHRocm91Z2ggYSBzZXJpZXMgb2YgaW5jbHVkZWQgCmV4ZXJjaXNlcyB1c2luZyB0aGUgdG9vbHMgd2UndmUganVzdCBsZWFybmVkIGFuZCB3aWxsIGxlYXJuIGFib3V0LiAKCgpUaGUgZGF0YSBmb3IgdGhlIGV4ZXJjaXNlcyBgRWNvbm9taXN0RGF0YS5jc3ZgIGNhbiBiZSBkb3dubG9hZGVkIGZyb20gCnRoZSBjbGFzcyBnaXRodWIgcmVwb3NpdG9yeS4KCmBgYHtyfQp1cmwgPC0gcGFzdGUwKCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vY21lMTk1L2NtZTE5NS5naXRodWIuaW8vIiwKICAgICAgICAgICAgICAibWFzdGVyL2Fzc2V0cy9kYXRhL0Vjb25vbWlzdERhdGEuY3N2IikKZGF0IDwtIHJlYWQuY3N2KHVybCkKaGVhZChkYXQpCmBgYAoKCiMgRXhlcmNpc2UgMQoKMS4gQ3JlYXRlIGEgc2NhdHRlciBwbG90IHdpdGggcGVyY2VudCBvZiBwZW9wbGUgb3ZlciB0aGUgYWdlIG9mIDE1IHdpdGggYSBiYW5rIAphY2NvdW50IG9uIHRoZSB4IGF4aXMgYW5kIHRoZSBTRURBIHNjb3JlIG9uIHRoZSB5IGF4aXMuCjIuIENvbG9yIHRoZSBwb2ludHMgaW4gdGhlIHByZXZpb3VzIHBsb3QgYmx1ZS4KMy4gQ29sb3IgdGhlIHBvaW50cyBpbiB0aGUgcHJldmlvdXMgcGxvdCBhY2NvcmRpbmcgdG8gdGhlIGBSZWdpb25gLgo0LiBDcmVhdGUgYm94cGxvdHMgb2YgU0VEQSBzY29yZXMgYnkgYFJlZ2lvbmAuCjUuIE92ZXJsYXkgcG9pbnRzIG9uIHRvcCBvZiB0aGUgYm94IHBsb3RzCgoKYGBge3J9CiMxLiBDcmVhdGUgYSBzY2F0dGVyIHBsb3Qgd2l0aCBwZXJjZW50IG9mIHBlb3BsZSBvdmVyIHRoZSBhZ2Ugb2YgMTUgd2l0aCBhIGJhbmsgCnAgPC0gZ2dwbG90KGRhdCwgYWVzKHggPSBQZXJjZW50Lm9mLjE1cGx1cy53aXRoLmJhbmsuYWNjb3VudCwgeSA9IFNFREEuQ3VycmVudC5sZXZlbCkpIApwICsgZ2VvbV9wb2ludCgpCmBgYAoKYGBge3J9CiMyLiBDb2xvciB0aGUgcG9pbnRzIGluIHRoZSBwcmV2aW91cyBwbG90IGJsdWUuCnAgKyBnZW9tX3BvaW50KGNvbG9yID0gImJsdWUiKQpgYGAKCmBgYHtyfQojMy4gQ29sb3IgdGhlIHBvaW50cyBpbiB0aGUgcHJldmlvdXMgcGxvdCBhY2NvcmRpbmcgdG8gdGhlIGBSZWdpb25gLgpwICsgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBSZWdpb24pKQpgYGAKCmBgYHtyfQojNC4gQ3JlYXRlIGJveHBsb3RzIG9mIFNFREEgc2NvcmVzIGJ5IGBSZWdpb25gLgpib3hwbG90IDwtIGdncGxvdChkYXQsIGFlcyh4ID0gUmVnaW9uLCB5ID0gU0VEQS5DdXJyZW50LmxldmVsKSkgKyBnZW9tX2JveHBsb3QoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAxNSwgaGp1c3QgPSAxKSkKYm94cGxvdApgYGAKCmBgYHtyfQojNS4gT3ZlcmxheSBwb2ludHMgb24gdG9wIG9mIHRoZSBib3ggcGxvdHMKYm94cGxvdCArIGdlb21fcG9pbnQoKQpgYGAKCmBgYHtyfQojNS4gT3ZlcmxheSBwb2ludHMgb24gdG9wIG9mIHRoZSBib3ggcGxvdHMKYm94cGxvdCArIGdlb21faml0dGVyKHdpZHRoID0gMC40KQpgYGAKCgojIEV4ZXJjaXNlIDIKCjEuIFJlLWNyZWF0ZSBhIHNjYXR0ZXIgcGxvdCB3aXRoIHBlcmNlbnQgb2YgcGVvcGxlIGFnZWQgMTUrIHdpdGggYSBiYW5rIGFjY291bnQKb24gdGhlIHggYXhpcyBhbmQgU0VEQSBjdXJyZW50IGxldmVsIHNjb3JlIG9uIHRoZSB5IGF4aXMgCihhcyB5b3UgZGlkIGluIHRoZSBwcmV2aW91cyBleGVyY2lzZSkuCjIuIE92ZXJsYXkgYSBzbW9vdGhpbmcgbGluZSBvbiB0b3Agb2YgdGhlIHNjYXR0ZXIgcGxvdCB1c2luZyB0aGUgbG0gbWV0aG9kLiAKSGludDogc2VlIGA/c3RhdF9zbW9vdGhgLgozLiBPdmVybGF5IGEgc21vb3RoaW5nIGxpbmUgb24gdG9wIG9mIHRoZSBzY2F0dGVyIHBsb3QgdXNpbmcgdGhlIGRlZmF1bHQgbWV0aG9kLgo0LiBPdmVybGF5IGEgc21vb3RoaW5nIGxpbmUgb24gdG9wIG9mIHRoZSBzY2F0dGVyIHBsb3QgdXNpbmcgdGhlIGRlZmF1bHQgbG9lc3MgCm1ldGhvZCwgYnV0IG1ha2UgaXQgbGVzcyBzbW9vdGguIEhpbnQ6IHNlZSBgP2xvZXNzYC4KCmBgYHtyfQojMS4gUmUtY3JlYXRlIGEgc2NhdHRlciBwbG90CnAgPC0gZ2dwbG90KGRhdCwgYWVzKHggPSBQZXJjZW50Lm9mLjE1cGx1cy53aXRoLmJhbmsuYWNjb3VudCwgeSA9IFNFREEuQ3VycmVudC5sZXZlbCkpCihwIDwtIHAgKyBnZW9tX3BvaW50KCkpCmBgYAoKYGBge3J9CiMyLiBPdmVybGF5IGEgc21vb3RoaW5nIGxpbmUgb24gdG9wIG9mIHRoZSBzY2F0dGVyIHBsb3QgdXNpbmcgdGhlIGxtIG1ldGhvZApwICsgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikKYGBgCgpgYGB7cn0KIzMuIE92ZXJsYXkgYSBzbW9vdGhpbmcgbGluZSBvbiB0b3Agb2YgdGhlIHNjYXR0ZXIgcGxvdCB1c2luZyB0aGUgZGVmYXVsdCBtZXRob2QuCnAgKyBnZW9tX3Ntb290aCgpCmBgYAoKYGBge3J9CiM0LiBPdmVybGF5IGEgc21vb3RoaW5nIGxpbmUgb24gdG9wIG9mIHRoZSBzY2F0dGVyIHBsb3QgdXNpbmcgdGhlIGRlZmF1bHQgbG9lc3MgCiMgbWV0aG9kLCBidXQgbWFrZSBpdCBsZXNzIHNtb290aApwICsgZ2VvbV9zbW9vdGgoc3BhbiA9IDAuMikKYGBgCgoKIyBFeGVyY2lzZSAzCgoxLiBGb3IgdGhlIHNjYXR0ZXIgcGxvdCBvZiAlIG9mIHBwbCBhZ2VkIDE1KyB3aXRoIGJhbmsgYWNjb3VudCB2cyBTRURBIHNjb3JlCmNvbG9yZWQgYnkgcmVnaW9uLCBnZW5lcmF0ZWQgaW4gRXhlcmNpc2UgSS4zIG1vZGlmeSB0aGUgY29sb3Igc2NhbGUgdG8gCnVzZSBzcGVjaWZpYyB2YWx1ZXMgb2YgeW91ciBjaG9vc2luZy4gSGludDogc2VlIGA/c2NhbGVfY29sb3JfbWFudWFsYC4KCmBgYHtyfQpwRWMgPC0gZ2dwbG90KGRhdCwgYWVzKFBlcmNlbnQub2YuMTVwbHVzLndpdGguYmFuay5hY2NvdW50LCBTRURBLkN1cnJlbnQubGV2ZWwpKSAKKHBFYyA8LSBwRWMgKyBnZW9tX3BvaW50KGFlcyhjb2xvciA9IFJlZ2lvbikpICsgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpKQpgYGAKCiMgRXhlcmNpc2UgNAoKMS4gRmFjZXQgIGJ5IHJlZ2lvbiAoYH4gUmVnaW9uYCkgdGhlIHRoZSBFY29ub21pc3QgcGxvdCBmcm9tIEV4ZXJjaXNlIDMuCgpgYGB7cn0KcEVjICsgZmFjZXRfd3JhcCh+IFJlZ2lvbikKYGBgCgoKCiMgRXhlcmNpc2UgNTogRmluaXNoIHRoZSBFY29ub21pc3QgcGxvdC4KCjEuIENoYW5nZSBvcmRlciBvZiB0aGUgUmVnaW9ucwoyLiBBZGQgdGhlIGxpbmVhciB0cmVuZAozLiBDaGFuZ2UgdGhlIGF4ZXMgcmF0aW8uCjQuIENoYW5nZSB0aGUgY29sb3Igc2NoZW1lLiBVc2UgdGhlc2UgY29sb3JzIApgY29sb3JzIDwtICBjKCIjMjhBQURDIiwiI0YyNTgzRiIsICIjNzZDMEMxIiwiIzI0NTc2RCIsICIjMjQ4RTg0IiwiI0RDQzNBQSIsICIjOTY1MDNGIilgCjUuIEFkZCBhIHRpdGxlIGFuZCBmb3JtYXQgdGhlIGF4ZXMKNi4gQ2hhbmdlIHRoZSBiYWNrZ3JvdW5kIGFuZCB0aGVtZQo3LiBGb3JtYXQgdGhlIGxlZ2VuZAo4LiBBZGQgcG9pbnQgbGFiZWxzCgoKIyMjIENoYW5nZSBvcmRlciBvZiB0aGUgUmVnaW9ucwoKYGBge3J9CmRhdCRSZWdpb24gPC0gYXMuY2hhcmFjdGVyKGRhdCRSZWdpb24pCmRhdCRSZWdpb24gPC0gZmFjdG9yKGRhdCRSZWdpb24sIAogICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJFdXJvcGUiLCAiQXNpYSIsICJPY2VhbmlhIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vcnRoIEFtZXJpY2EiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGF0aW4gQW1lcmljYSAmIHRoZSBDYXJpYmJlYW4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWlkZGxlIEVhc3QgJiBOb3J0aCBBZnJpY2EiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdWItU2FoYXJhbiBBZnJpY2EiKSwKICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiRXVyb3BlIiwgIkFzaWEiLCAiT2NlYW5pYSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOb3J0aCBBbWVyaWNhIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkxhdGluIEFtZXJpY2EgJiBcbiB0aGUgQ2FyaWJiZWFuIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1pZGRsZSBFYXN0ICYgXG4gTm9ydGggQWZyaWNhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3ViLVNhaGFyYW4gXG4gQWZyaWNhIikpCmBgYAoKCmBgYHtyfQpwRWMgPC0gZ2dwbG90KGRhdCwgYWVzKFBlcmNlbnQub2YuMTVwbHVzLndpdGguYmFuay5hY2NvdW50LCBTRURBLkN1cnJlbnQubGV2ZWwpKSAKcEVjICsgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBSZWdpb24pKQpgYGAKCiMjIyBBZGQgdGhlIGxpbmVhciB0cmVuZAoKYGBge3J9CnBFYyA8LSBwRWMgKyBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEZBTFNFLCBjb2wgPSAiYmxhY2siLCBzaXplID0gMC41KSAKKHBFYyA8LSBwRWMgKyBnZW9tX3BvaW50KGFlcyhmaWxsID0gUmVnaW9uKSwgY29sb3IgPSAid2hpdGUiLCBzaGFwZSA9IDIxLCBzaXplID00KSkgCmBgYAoKIyMjIENoYW5nZSB0aGUgYXhlcyByYXRpby4KCmBgYHtyfQoocEVjIDwtIHBFYyArIGNvb3JkX2ZpeGVkKHJhdGlvID0gMC40KSkKYGBgCgojIyMgQ2hhbmdlIHRoZSBjb2xvciBzY2hlbWUKCmBgYHtyfQpjb2xvcnMgPC0gIGMoIiMyOEFBREMiLCIjRjI1ODNGIiwgIiM3NkMwQzEiLCIjMjQ1NzZEIiwgCiAgICAgICAgICAgICAiIzI0OEU4NCIsIiNEQ0MzQUEiLCAiIzk2NTAzRiIpCihwRWMgPC0gcEVjICsgc2NhbGVfZmlsbF9tYW51YWwobmFtZSA9ICIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGNvbG9ycykpCmBgYAoKCiMjIyBBZGQgYSB0aXRsZSBhbmQgZm9ybWF0IHRoZSBheGVzCgpgYGB7cn0KKHBFYyA8LSBwRWMgKwogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIiUgb2YgcGVvcGxlIGFnZWQgMTUrIHdpdGggYmFuayBhY2NvdW50LCAyMDE0IiwKICAgICAgICAgICAgICAgICAgICAgbGltaXRzID0gYygwLCAxMDApLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBzZXEoMCwgMTAwLCBieSA9IDIwKSkgKwogIHNjYWxlX3lfY29udGludW91cyhuYW1lID0gIlNFREEgU2NvcmUsIDEwMC1tYXhpbXVtIiwKICAgICAgICAgICAgICAgICAgICAgbGltaXRzID0gYygwLCAxMDApLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBzZXEoMCwgMTAwLCBieSA9IDIwKSkgKwogIGdndGl0bGUoIkxhdWdoaW5nIGFsbCB0aGUgd2F5IHRvIHRoZSBiYW5rIFxuIFdlbGwtYmVpbmcgYW1kIGZpbmFuY2lhbCBpbmNsdXNpb24gXG4gMjAxNC0xNSIpKQpgYGAKCiMjIyBDaGFuZ2UgdGhlIGJhY2tncm91bmQgYW5kIHRoZW1lCgpZb3UgY2FuIGNoZWNrIG91dCB0aGUgW2BnZ3RoZW1lc2BdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9nZ3RoZW1lcy92aWduZXR0ZXMvZ2d0aGVtZXMuaHRtbCkgCnBhY2thZ2Ugd2hpY2ggaW1wbGVtZW50IHRoZSB0aGVtZXMgdGhhdCBtYWtlIHlvdXIgcGxvdHMgbG9vayBsaWtlIHRoZXkgY2FtZSBmcm9tOgoKKiBCYXNlIGdyYXBoaWNzCiogVGFibGVhdQoqIEV4Y2VsCiogU3RhdGEKKiBFY29ub21pc3QKKiBXYWxsIFN0cmVldCBKb3VybmFsCiogRWR3YXJkIFR1ZnRlCiogTmF0ZSBTaWx2ZXIncyBGaXZldGhpcnR5ZWlnaHQKKiBldGMuCgpgYGB7cn0KIyBpbnN0YWxsLnBjYWthZ2VzKCJnZ3RoZW1lcyIpCmxpYnJhcnkoZ2d0aGVtZXMpCihwRWMgPC0gcEVjICsgdGhlbWVfZWNvbm9taXN0X3doaXRlKGdyYXlfYmc9RkFMU0UpKQpgYGAKCiMjIyBGb3JtYXQgdGhlIGxlZ2VuZAoKYGBge3IsIGZpZy53aWR0aD05LCBmaWcuaGVpZ2h0PTV9CihwRWMgPC0gcEVjICsgY29vcmRfZml4ZWQoMC40KSArCiAgIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiZ3JleTM3Iiwgc2l6ZSA9IDEyKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSBjKDAuNDUsIDEuMSksICMgcG9zaXRpb24gdGhlIGxlZ2VuZCBpbiB0aGUgdXBwZXIgbGVmdCAKICAgICAgICBsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiLAogICAgICAgIGxlZ2VuZC5qdXN0aWZpY2F0aW9uID0gMC4xLCAjIGFuY2hvciBwb2ludCBmb3IgbGVnZW5kLnBvc2l0aW9uLgogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgY29sb3IgPSAiZ3JheTEwIiksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gcmVsKDEuMSksIGNvbG9yID0gImJsYWNrIiksCiAgICAgICAgcGxvdC5tYXJnaW4gPSB1bml0KGMoMSwgMS41LCAxLjUsIDAuNSksICJjbSIpKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQobmNvbCA9IDQsIGJ5cm93ID0gRkFMU0UpKSkKYGBgCgojIyMgQWRkIHBvaW50IGxhYmVscwoKYGBge3J9CnBvaW50c1RvTGFiZWwgPC0gYygiWWVtZW4iLCAiSXJhcSIsICJFZ3lwdCIsICJKb3JkYW4iLCAiQ2hhZCIsICJDb25nbyIsIAogICAgICAgICAgICAgICAgICAgIkFuZ29sYSIsICJBbGJhbmlhIiwgIlppbWJhYndlIiwgIlVnYW5kYSIsICJOaWdlcmlhIiwKICAgICAgICAgICAgICAgICAgICJVcnVndWF5IiwgIkthemFraHN0YW4iLCAiSW5kaWEiLCAiVHVya2V5IiwgIlNvdXRoIEFmcmljYSIsCiAgICAgICAgICAgICAgICAgICAiS2VueWEiLCAiUnVzc2lhIiwgIkJyYXppbCIsICJDaGlsZSIsICJTYXVkaSBBcmFiaWEiLCAKICAgICAgICAgICAgICAgICAgICJQb2xhbmQiLCAiQ2hpbmEiLCAiU2VyYmlhIiwgIlVuaXRlZCBTdGF0ZXMiLCAiVW5pdGVkIEtpbmdkb20iKQpgYGAKCmBgYHtyLCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD01fQoocEVjVGV4dCA8LSAgcEVjICsgZ2VvbV90ZXh0X3JlcGVsKGFlcyhsYWJlbCA9IENvdW50cnkpLCBjb2xvciA9ICJncmF5MjAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHN1YnNldChkYXQsIENvdW50cnkgJWluJSBwb2ludHNUb0xhYmVsKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlID0gMjApKQpgYGAKCiMjIyBBZGQgbm90ZXMgdG8gdGhlIGJvdHRvbSBhbmQgc2F2ZSB0aGUgcGxvdAoKVXNlICJncmlkLnRleHQoKSIgdG8gYWRkIG5vdGVzCgpgYGB7cn0KbGlicmFyeShncmlkKQpwbmcoZmlsZSA9ICIuL2Vjb25TY2F0dGVyLnBuZyIsIHdpZHRoID0gODAwLCBoZWlnaHQgPSA2MDApCnBFY1RleHQKZ3JpZC50ZXh0KCJTb3VyY2U6IEJvc3RvbiBDb25zdWx0aW5nIEdyb3VwIiwKICAgICAgICAgeCA9IC4wMiwgeSA9IC4wNCwganVzdCA9ICJsZWZ0IiwKICAgICAgICAgZHJhdyA9IFRSVUUsIGdwPWdwYXIoZm9udHNpemU9MTAsIGNvbD0iZ3JleTM3IikpCmdyaWQudGV4dCgiRGF0YSBhdmFpbGFibGUgZm9yIDEyMyBjb3VudHJpZXMgXG4gU3VzdGFpbmFibGUgZWNvbm9taWMgZGV2ZWxvcG1lbnQgYXNzZXNtZW50IiwKICAgICAgICAgeCA9IDAuOTgsIHkgPSAuMDYsIGp1c3QgPSAicmlnaHQiLAogICAgICAgICAgZHJhdyA9IFRSVUUsIGdwPWdwYXIoZm9udHNpemU9MTAsIGNvbD0iZ3JleTM3IikpCmRldi5vZmYoKQpgYGAKIVtdKC4vZWNvblNjYXR0ZXIucG5nKQoKClNpbWlsYXIgdG8gdGhlIG9yaWdpbmFsOgoKIVtdKC4vZWNvbm9taXN0LnBuZykK